package io.hellsinger.vortex.ui.component.item.drawer

import android.content.Context
import android.content.res.ColorStateList
import android.graphics.drawable.Drawable
import android.graphics.drawable.RippleDrawable
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import io.hellsinger.vortex.ui.component.ViewMeasure
import io.hellsinger.vortex.ui.component.adapter.holder.RecyclableView
import io.hellsinger.vortex.ui.component.dp
import io.hellsinger.vortex.ui.component.drawable.RoundedCornerDrawable
import io.hellsinger.vortex.ui.component.item.menu.MenuAction

class DrawerItemView(
    context: Context,
) : FrameLayout(context),
    RecyclableView<MenuAction> {
    private val iconHorizontalPadding = 16.dp
    private val titleHorizontalPadding = 32.dp
    private val iconSize = 24.dp

    private val surface =
        RoundedCornerDrawable(
            color = 0,
            radius = 8F.dp,
            paddingLeft = 8.dp,
            paddingRight = 8.dp,
            paddingBottom = 4.dp,
            paddingTop = 4.dp,
        )

    private val iconView =
        ImageView(context).apply {
            layoutParams = LayoutParams(24.dp, 24.dp)
        }

    private val titleView =
        TextView(context).apply {
            textSize = 16F
            layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
        }

    var icon: Drawable?
        get() = iconView.drawable
        set(value) {
            iconView.setImageDrawable(value)
        }

    private val isEmptyIcon: Boolean
        get() = icon == null

    var title: CharSequence?
        get() = titleView.text
        set(value) {
            titleView.text = value
        }

    init {
        isClickable = true
        isFocusable = true

        addView(iconView)
        addView(titleView)

        background = surface
        foreground = createForegroundDrawable()
    }

    override fun onMeasure(
        widthMeasureSpec: Int,
        heightMeasureSpec: Int,
    ) {
        ViewMeasure(
            widthMeasureSpec,
            heightMeasureSpec,
            ViewGroup.LayoutParams.MATCH_PARENT,
            48,
            ::setMeasuredDimension,
        )

        measureChildren(widthMeasureSpec, heightMeasureSpec)
    }

    override fun onLayout(
        changed: Boolean,
        left: Int,
        top: Int,
        right: Int,
        bottom: Int,
    ) {
        var widthLeft = iconHorizontalPadding
        if (!isEmptyIcon) {
            iconView.layout(
                widthLeft,
                (measuredHeight - iconView.measuredHeight) shr 1,
                widthLeft + iconView.measuredWidth,
                ((measuredHeight - iconView.measuredHeight) shr 1) + iconView.measuredHeight,
            )
            widthLeft += iconSize
        }

        if (!isEmptyIcon) {
            widthLeft += titleHorizontalPadding
        }

        titleView.layout(
            widthLeft,
            (height - titleView.lineHeight) shr 1,
            widthLeft + titleView.measuredWidth,
            ((height - titleView.lineHeight) shr 1) + titleView.measuredHeight,
        )
    }

    override fun onBind(item: MenuAction) {
        id = item.id
        icon = item.icon
        title = item.title
    }

    override fun onUnbind() {
        title = null
        icon = null
    }

    override fun onBindListener(listener: OnClickListener?) {
        setOnClickListener(listener)
    }

    override fun onBindSelection(isSelected: Boolean) {
        setSelected(isSelected)
    }

    override fun onUnbindListeners() {
        setOnClickListener(null)
    }

    override fun setBackgroundColor(color: Int) {
        surface.setColor(color)
    }

    fun setRippleColor(color: Int) {
        (foreground as RippleDrawable).setColor(ColorStateList.valueOf(color))
    }

    fun setTitleColor(color: Int) {
        titleView.setTextColor(color)
    }

    fun setIconColor(color: Int) {
        iconView.imageTintList = ColorStateList.valueOf(color)
    }

    private fun createForegroundDrawable(): RippleDrawable =
        RippleDrawable(
            ColorStateList.valueOf(0),
            null,
            surface,
        )
}
